package com.cn.qtms.base.controller;

import com.cn.qtms.base.entity.BaseEntity;
import com.cn.qtms.base.service.BaseService;
import com.cn.qtms.common.constant.CodeNameConstants;
import com.cn.qtms.common.page.PageRes;
import com.cn.qtms.common.result.QueryParam;
import com.cn.qtms.common.result.Result;
import com.cn.qtms.common.result.ResultUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@Api
/**
 * @Name:BaseController
 * @Description:
 * @Author: zhangyang
 * @Date: 2019-08-26 23:45
 **/
public abstract class BaseController<T extends BaseEntity, ID> extends BaseJpaController {

    @Autowired
    HttpServletRequest servletRequest;

    /**
     * 获取service层方法
     * @return
     */
    protected abstract BaseService<T, ID> getService();

    /**
     * 动态拼接条件查询sql集合
     *
     * @param request
     * @return
     */
    @ApiOperation(value = "list", notes = "根据条件动态查询数据")
    @ApiImplicitParam(name = "request", value = "查询条件集合", required = true, dataType = "JSON")
    @PostMapping(value = "list")
    public Result<PageRes<T>> list(@RequestBody QueryParam request) {
        return getService().page(request);
    }

    /***
     *@Name feignList
     *@Description feign-远程查询列表信息
     *@Param [request]
     *@Return java.util.List<T>
     *@Author zhangyang
     *@Date 2019/8/31
     */
    @PostMapping(value = "feign-list")
    public List<T> feignList(@RequestBody HashMap<String,Object> request) {
        String header = servletRequest.getHeader(CodeNameConstants.REQUEST_HEADER_AUTH);
        return getService().list(request);
    }

    /**
     * 根据id获取对象
     *
     * @param id
     * @return
     */
    @GetMapping(value = "id/{id}")
    @ApiOperation(value = "id方法", notes = "查询数据详情")
    @ApiImplicitParam(paramType = "path", name = "id", value = "编号", required = true, dataType = "Long")
    public Result<T> getById(@PathVariable ID id) {
        T t = feignId(id);
        return ResultUtil.success(t);
    }

    /**
     * @Name feignId
     * @Description feign-id 回去详情信息方法
     * @Param [id]
     * @Return T
     * @Author zhangyang
     * @Date 2019/8/31
     */
    @GetMapping(value = "feign-id/{id}")
    public T feignId(@PathVariable ID id) {
        return getService().findById(id);
    }

    @GetMapping(value = "count")
    @ApiOperation(value = "根据条件获取总数", notes = "根据条件获取总数")
    @ApiImplicitParam(name = "request", value = "", required = true, dataType = "json")
    public Result<String> count(@RequestParam HashMap<String, Object> request) {
        long count = feignCount(request);
        return ResultUtil.success(String.valueOf(count));
    }

    @GetMapping(value = "feign-count")
    public long feignCount(@RequestParam HashMap<String, Object> request) {
        return getService().findCount(request);
    }

    /**
     * 新增方法
     *
     * @param model
     * @return
     * @throws Exception
     */
    @PostMapping(value = "create")
    @ApiOperation(value = "新增方法", notes = "单条数据新增")
    @ApiImplicitParam(name = "model", value = "新建实例", required = true, dataType = "JSON")
    public Result<T> create(@Valid @RequestBody T model) throws Exception {
        T t = feignCreate(model);
        return ResultUtil.success(t);
    }

    /**
     * @Name feignCreate
     * @Description 远程feign调用create方法
     * @Param [model]
     * @Return T
     * @Author zhangyang
     * @Date 2019/8/31
     */
    @PostMapping("feign-create")
    public T feignCreate(@Valid @RequestBody T model) throws Exception {
        return getService().create(model);
    }

    @PostMapping(value = {"createList","feign-createList"})
    @ApiOperation(value = "批量新增方法", notes = "批量新增对象到数据库")
    @ApiImplicitParam(name = "list", value = "新建对象集合", required = true, dataType = "JSON")
    public List<T> createList(@Valid @RequestBody List<T> list) throws Exception {
        return getService().createList(list);
    }

    /**
     * 修改方法
     *
     * @param model
     * @return
     * @throws Exception
     */
    @PostMapping(value = "update")
    @ApiOperation(value = "单条修改方法", notes = "修改单条数据")
    @ApiImplicitParam(name = "model", value = "待修改对象", required = true, dataType = "JSON")
    public Result<T> update(@Valid @RequestBody T model) throws Exception {
        T t = feignUpdate(model);
        return ResultUtil.success(t);
    }

    @PostMapping("feign-update")
    public T feignUpdate(@Valid @RequestBody T model) throws Exception {
        return getService().update(model);
    }

    @PostMapping(value = "updateState")
    @ApiOperation(value = "修改部分字段", notes = "单条数据修改部分字段")
    @ApiImplicitParam(name = "request", value = "map", required = true, dataType = "map")
    public Result<T> updateState(@RequestBody HashMap<String, Object> map) {
        T t = getService().updateState(map);
        return ResultUtil.success(t);
    }

    /**
     * 单条数据删除
     *
     * @param id
     * @return
     */
    @PostMapping(value = "del/{id}")
    @ApiOperation(value = "单条删除方法", notes = "逻辑删除单条数据")
    @ApiImplicitParam(paramType = "path", name = "id", value = "待删除id", required = true, dataType = "Integer")
    public Result<T> delete(@PathVariable ID id) {
        T del = getService().del(id);
        return ResultUtil.success(del);
    }

    @PostMapping(value = "del")
    @ApiOperation(value = "批量删除方法", notes = "批量删除数据")
    @ApiImplicitParam(name = "map", value = "需要删除的数组", required = true, dataType = "JSON")
    public Result<List<T>> delete(@RequestBody Map<String, ID[]> map) {
        List<T> del = getService().del(map);
        return ResultUtil.success(del);
    }
}
